package cn.yitun.chat.yitunserverimapicore.business.chat.action;

import cn.yitun.chat.yituncommonmessage.ExceptionEnum;
import cn.yitun.chat.yituncommonmessage.YitunException;
import cn.yitun.chat.yituncommonmessage.impl.HeadImpl;
import cn.yitun.chat.yituncommonmessage.result.ResultMessage;
import cn.yitun.chat.yituncommonutil.YitunStringUtil;
import cn.yitun.chat.yitungeneral.annotation.action.ActionMapping;
import cn.yitun.chat.yitungeneral.annotation.parameter.JsonDefine;
import cn.yitun.chat.yitunnetsession.session.SocketSession;
import cn.yitun.chat.yitunservercommonlib.constant.ActionTypeConstant;
import cn.yitun.chat.yitunservercommonlib.dataentity.data.base.chat.UserOfflineContent;
import cn.yitun.chat.yitunservercommonlib.dataentity.data.base.chat.UserOfflineCount;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.userchat.LastChatDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.userchat.UserChatContentDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.system.user.UserVo;
import cn.yitun.chat.yitunservercommonlib.util.NumUtil;
import cn.yitun.chat.yitunservercommonlib.util.R;
import cn.yitun.chat.yitunservercommonlib.util.codec.IdGen;
import cn.yitun.chat.yitunserverimapicore.business.chat.service.LastChatUserService;
import cn.yitun.chat.yitunserverimapicore.business.chat.service.UserChatHistoryService;
import cn.yitun.chat.yitunserverimapicore.business.chat.service.UserChatService;
import cn.yitun.chat.yitunserverimapicore.business.user.service.UserService;
import cn.yitun.chat.yitunserverimcore.general.main.push.chat.UserChatPush;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@ActionMapping(value = ActionTypeConstant.USER_CHAT_ACTION_PUSH)
public class UserChatAction {
	@Resource
	UserChatService userChatService;
	@Resource
	UserChatHistoryService userChatLogService;
	@Resource
	UserChatPush userChatPush;
	@Resource
	LastChatUserService lastChatUserService;
	@Resource
	private UserService userService;

	/**
	 * 
	 * Description 向用户发送抖动 <br>
	 * Date 2019-05-22 17:57:32<br>
	 * 
	 * @param head
	 * @param socketSession
	 * @param query
	 * @since 1.0.0
	 */
	@ActionMapping(value = "1.1.0000")
	public void userAction(
			HeadImpl head,
			SocketSession socketSession,
			@JsonDefine("data") UserChatContentDto query) {
		if (NumUtil.isInValid(query.getReceiveUserId()))
			throw new YitunException(ExceptionEnum.LOSE_FILED);

		userChatPush.motion(head.getKey(), socketSession.getKey(), query);
	}

	/**
	 * 
	 * Date 2019-02-17 17:51:26<br>
	 * Description 向用户发送私聊信息
	 * 
	 * @param head
	 * @param query
	 * @author yitun<br>
	 * @version 1.1
	 */
	@ActionMapping(value = "1.1.0001")
	public void userChat(HeadImpl head,
						 @JsonDefine("data") UserChatContentDto query) {
		if (NumUtil.isInValid(query.getSendUserId()) || NumUtil.isInValid(query.getReceiveUserId()))
			throw new YitunException(ExceptionEnum.LOSE_FILED);
		Long key = null == head.getKey() ? IdGen.getNumber() : head.getKey();
		userChatService.userChat(key, query);
	}

	/**
	 * 
	 * Description 标记信息为已读 <br>
	 * Date 2019-05-25 08:23:23<br>
	 * 
	 * @param socketSession
	 * @param query
	 * @since 1.0.0
	 */
	@ActionMapping(value = "1.1.0002")
	public void updateToRead(SocketSession socketSession,
							 @JsonDefine("data") UserChatContentDto query) {
		if (NumUtil.isInValid(query.getSendUserId()) || NumUtil.isInValid(query.getId()))
			throw new YitunException(ExceptionEnum.LOSE_FILED);

		Long receiveUserId = socketSession.getKey();
		userChatLogService.updateUserOfflineMessageToRead(receiveUserId, query.getSendUserId(), query.getId(), null);
	}

	/**
	 * 
	 * Description 查询聊天历史 <br>
	 * Date 2019-05-25 08:04:43<br>
	 * 
	 * @param head
	 * @param query
	 * @return Object
	 * @since 1.0.0
	 */
	@ActionMapping(value = "1.1.0004")
	public Object queryUserChatLog(HeadImpl head, @JsonDefine("data") UserChatContentDto query) {

		return userChatLogService.queryUserChatLogList(query);
	}


	/**
	 * 
	 * Description 获取私聊聊天记录（此方法主要以消息key为条件） <br>
	 * Date 2019-05-25 08:05:13<br>
	 * 
	 * @param head
	 * @param query
	 * @return Object
	 * @since 1.0.0
	 */
	@ActionMapping(value = "1.1.0005")
	public Object getUserChatLogByMessageKey(HeadImpl head, @JsonDefine("data") UserChatContentDto query) {

		if (NumUtil.isInValid(query.getSendUserId()) || NumUtil.isInValid(query.getReceiveUserId())
				|| NumUtil.isInValid(query.getMessageId()) || YitunStringUtil.isEmpty(query.getDirection()))
			throw new YitunException(ExceptionEnum.LOSE_FILED);

		return userChatLogService.getUserChatLogListByStartMessageKey(query);
	}

	/**
	 * 
	 * Description 获取私聊聊天记录（此方法主要以数据库id为条件） <br>
	 * Date 2019-05-25 08:04:55<br>
	 * 
	 * @param head
	 * @param query
	 * @return Object
	 * @since 1.0.0
	 */
	@ActionMapping(value = "1.1.0006")
	public Object getUserChatLog(HeadImpl head, @JsonDefine("data") UserChatContentDto query) {

		if (NumUtil.isInValid(query.getSendUserId()) || NumUtil.isInValid(query.getReceiveUserId())
				|| NumUtil.isInValid(query.getStartId()) || YitunStringUtil.isEmpty(query.getDirection()))
			throw new YitunException(ExceptionEnum.LOSE_FILED);

		return userChatLogService.getUserChatLogListByStartId(query);
	}

	/**
	 * 
	 * Description 获取最近聊天列表（含最后聊天内容）<br>
	 * 此接口包含聊天对象详细信息和聊天内容 <br>
	 * Date 2019-05-25 08:37:11<br>
	 * 
	 * @param head
	 * @param socketSession
	 * @return Object
	 * @since 1.0.0
	 */
	@ActionMapping(value = "1.1.0007")
	public Object getLastChatWithContentList(HeadImpl head,
			SocketSession socketSession,
			@JsonDefine("data") LastChatDto query) {

//		userId = socketSession.getKey() ;
		if (NumUtil.isInValid(query.getUserId()))
			throw new YitunException(ExceptionEnum.LOSE_FILED);

		return new ResultMessage(R.param("list", lastChatUserService.getLastChatWithContentList(query)));
	}

	/**
	 *
	 * Description 查询聊天历史 <br>
	 * Date 2019-05-25 08:04:43<br>
	 *
	 * @param head
	 * @param query
	 * @return Object
	 * @since 1.0.0
	 */
	@ActionMapping(value = "1.1.0008")
	public Object queryUserChatLogBySendAndReceive(HeadImpl head, @JsonDefine("data") UserChatContentDto query) {
		if (NumUtil.isInValid(query.getSendUserId()) || NumUtil.isInValid(query.getReceiveUserId()))
			throw new YitunException(ExceptionEnum.LOSE_FILED);

		return userChatLogService.queryUserChatLogList(query);
	}

	@ActionMapping(value = "1.1.0010")
	public Object getUserOfflineContentList(HeadImpl head,
			SocketSession socketSession,
			@JsonDefine("data") UserChatContentDto query) {

//		Long userId = socketSession.getKey();
		if (NumUtil.isInValid(query.getReceiveUserId()))
			throw new YitunException(ExceptionEnum.LOSE_FILED);
		ResultMessage message = new ResultMessage();
		List<UserOfflineCount> countList = userChatLogService.getOfflineCountList(query);
		List<Long> userIds = new ArrayList<>();
		List<UserOfflineContent> list = new ArrayList<>();

		for (UserOfflineCount ap : countList) {
			userIds.add(ap.getSendUserId());
		}
		List<UserVo> users = userService.getUserDataList(userIds);
		Map<Long, UserVo> userMap = new HashMap<>();

		for (UserVo u : users) {
			userMap.put(u.getId(), u);
		}

		for (UserOfflineCount ap : countList) {
			int count = ap.getCount();
			Long uid = ap.getSendUserId();
			UserOfflineContent data = new UserOfflineContent();

			UserVo user = userMap.get(uid);
			data.setSendUser(user);
			data.setCount(count);
			list.add(data);
		}
		message.bodyPut("list", list);
		return message;
	}

	/**
	 * 
	 * Description 获取离线消息的发送者id列表<br>
	 * 此接口可以获取到哪些用户给自己发送了离线消息。<br>
	 * Date 2019-05-25 08:05:34<br>
	 * 
	 * @param head
	 * @param socketSession
	 * @return Object
	 * @since 1.0.0
	 */
	@ActionMapping(value = "1.1.0012")
	public Object getOfflineUserIdList(HeadImpl head, SocketSession socketSession) {
		Long userId = socketSession.getKey() ;
		List<Long> list = userChatLogService.getOfflineUserIdList(userId);
		return new ResultMessage(R.param("userIds", list));
	}

	/**
	 * 
	 * Description 获取离线消息数量 <br>
	 * Date 2019-05-25 08:26:16<br>
	 * 
	 * @param head
	 * @param socketSession
	 * @return Object
	 * @since 1.0.0
	 */
	@ActionMapping(value = "1.1.0014")
	public Object getOfflineCountList(HeadImpl head,
			SocketSession socketSession,
			@JsonDefine("data") UserChatContentDto query) {

//		Long userId = socketSession.getKey();
		if (NumUtil.isInValid(query.getReceiveUserId()))
			throw new YitunException(ExceptionEnum.LOSE_FILED);

		List<UserOfflineCount> list = userChatLogService.getOfflineCountList(query);
		return new ResultMessage(R.param("list", list));
	}

	/**
	 * 
	 * Description 获取指定用户的离线数量 <br>
	 * 根据离线发送者的用户id列表，获取离线消息数量<br>
	 * Date 2019-05-25 08:25:51<br>
	 * 
	 * @param head
	 * @param socketSession
	 * @param query
	 * @return Object
	 * @since 1.0.0
	 */
	@ActionMapping(value = "1.1.0015")
	public Object getOfflineCountListByIds(HeadImpl head,
			SocketSession socketSession,
			@JsonDefine("data") UserChatContentDto query) {

		Long userId = socketSession.getKey() ;
//		if (YitunCollectionUtil.isEmpty(query.getSendUserIds()))
//			throw new YitunException(ExceptionEnum.LOSE_FILED);
		query.setReceiveUserId(userId);
		List<UserOfflineCount> list = userChatLogService.getOfflineCountListBySendUserIds(query);
		return new ResultMessage(R.param("list", list));
	}
}
